﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
using System.Data;

using log4net;
using log4net.Config;

using SPW2HO.DataAccess;
using SPW2HO.CommonItems;

namespace SPW2HO.Classes
{
    public class Export
    {
        private static string AppPath = System.Windows.Forms.Application.StartupPath;

        private static readonly ILog log = LogManager.GetLogger(typeof(Export));
        public event EventHandler<CommonEventArgs> OnExportChanged;

        private static DirectoryInfo dirUpload = new DirectoryInfo(ConfigurationManager.AppSettings["UploadFolder"].ToString());

        private static string GetExportTime()
        {
            return DateTime.Now.ToString("yyyyMMddHHmmss");
        }

        private static string RemoveFileNameExtention(string FileName)
        {
            return FileName.Substring(0, FileName.LastIndexOf('.'));
        }

        private static void WriteObjectToXml(object obj, string FileName)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            xmlWriterSettings.CloseOutput = true;
            xmlWriterSettings.Indent = true;
            xmlWriterSettings.IndentChars = "\t";
            XmlWriter xmlWriter = XmlWriter.Create(FileName, xmlWriterSettings);
            xmlSerializer.Serialize(xmlWriter, obj);
            xmlWriter.Close();
        }

        public static void ExportProgramInfo(string ProgramID, string FileName)
        {
            ProgramInfoBO programInfoBO = ProgramInfoBO.GetById(ProgramID);
            WriteObjectToXml(programInfoBO, FileName);
        }

        public static void ExportPreviousPeriod(string ProgramID, string FileName)
        {
            PreviousPeriodBO previousPeriodBO = PreviousPeriodBO.GetById(ProgramID);
            WriteObjectToXml(previousPeriodBO, FileName);
        }

        public static void ExportBankerListBP(string ProgramID, string FileName)
        {
            DataTable dt = BankerListBpBO.GetBankerListByProgram(ProgramID);
            dt.TableName = "BankerListBP";
            dt.WriteXml(FileName, XmlWriteMode.WriteSchema, false);
        }

        public static void ExportBankerListSKU(string ProgramID, string FileName)
        {
                DataTable dt = BankerListSkuBO.GetBankerListSkuByProgram(ProgramID);
                dt.TableName = "BankerListSKU";
                dt.WriteXml(FileName, XmlWriteMode.WriteSchema, false);
        }

        public static void ExportBankerTarget(string ProgramID, string FileName)
        {
            DataTable dt = BankerTargetBO.GetBankerTargetByProgram(ProgramID);
            dt.TableName = "BankerTarget";
            dt.WriteXml(FileName, XmlWriteMode.WriteSchema, false);
        }

        public static void ExportProgramToDistributor(string ProgramID, string ShipToID)
        {
            try
            {
                log.Info("Begin export programID '" + ProgramID + "' for ShipToID '" + ShipToID + "'");
                FileInfo programInfo = new FileInfo(Path.Combine(AppPath, ProgramID + "_ProgramInfo.xml"));

                FileInfo previousPeriod = new FileInfo(Path.Combine(AppPath, ProgramID + "_PreviousPeriod.xml"));
                FileInfo bankerListBP = new FileInfo(Path.Combine(AppPath, ProgramID + "_BankerListBP.xml"));
                FileInfo bankerListSku = new FileInfo(Path.Combine(AppPath, ProgramID + "_BankerListSku.xml"));
                FileInfo bankerTarget = new FileInfo(Path.Combine(AppPath, ProgramID + "_BankerTarget.xml"));

                log.Info("- Finish create xml file paths");

                ExportProgramInfo(ProgramID, programInfo.FullName);
                ExportPreviousPeriod(ProgramID, previousPeriod.FullName);
                ExportBankerListBP(ProgramID, bankerListBP.FullName);
                ExportBankerListSKU(ProgramID, bankerListSku.FullName);
                ExportBankerTarget(ProgramID, bankerTarget.FullName);

                log.Info("- Finish export xml files");

                Cryptography Encoder = new Cryptography();
                string ZipFileName = ConfigurationManager.AppSettings["SPWProgramTargetFileName"].ToString();
                ZipFileName = ZipFileName.Replace("@SPWProgramCode", ProgramID.Trim());
                ZipFileName = ZipFileName.Replace("@ShipToID", ShipToID);
                ZipFileName = ZipFileName.Replace("@yyyyMMddHHmmss", GetExportTime()) + ".zip";
                string Pwd = Encoder.GenPWDByFilename(ZipFileName);

                FileInfo ZipFile = new FileInfo(Path.Combine(dirUpload.FullName, ZipFileName));

                string[] xmlFiles = { programInfo.FullName, 
                                        previousPeriod.FullName, 
                                        bankerListBP.FullName, 
                                        bankerListSku.FullName,
                                        bankerTarget.FullName};
                Zip.ZipFiles(xmlFiles, ZipFile.FullName, Pwd);

                log.Info("- Zip files completed");

                programInfo.Delete();
                previousPeriod.Delete();
                bankerListBP.Delete();
                bankerListSku.Delete();
                bankerTarget.Delete();
                log.Info("- Delete temp"); 
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.InnerException);
            }
            finally
            {
                log.Info("End export programID '" + ProgramID + "' for ShipToID '" + ShipToID + "'");
            }
        }

        public static void ExportSPWProgram(string ProgramID, List<string> AppliedShipTo, System.Windows.Forms.Label lbStatus)
        {            
            foreach (string ShipToID in AppliedShipTo)
            {
                ExportProgramToDistributor(ProgramID, ShipToID);
                lbStatus.Text = string.Format("Đang thực hiện export dữ liệu của chương trình {0} cho nhà phân phối {1}", ProgramID, ShipToID);
                lbStatus.Refresh();
            }
            lbStatus.Text = "Đã export dữ liệu thành công";
            lbStatus.Refresh();
        }

        private static void ExportApprovedActualTargetXML(string ProgramID, string ShipToID, string FileName)
        {
            DataTable dt = ActualTargetBO.GetActualTargetByProgramAndShipTo(ProgramID, ShipToID);
            dt.TableName = "ApprovedActualTarget";
            dt.WriteXml(FileName, XmlWriteMode.WriteSchema, false);
        }

        public static void ExportApprovedActualTarget(string ProgramID, string ShipToID)
        {
            try
            {
                log.Info("Begin export Approved Actual Target of ProgramID '" + ProgramID + "' for ShipToID '" + ShipToID + "'");
                FileInfo approvedActualTarget = new FileInfo(Path.Combine(AppPath, ProgramID + "_ApprovedActualTarget.xml"));

                log.Info("- Finish create xml file paths");

                ExportApprovedActualTargetXML(ProgramID, ShipToID, approvedActualTarget.FullName);
                log.Info("- Finish export xml files");

                Cryptography Encoder = new Cryptography();
                string ZipFileName = ConfigurationManager.AppSettings["ApprovedActualTargetFileName"].ToString();
                ZipFileName = ZipFileName.Replace("@SPWProgramCode", ProgramID.Trim());
                ZipFileName = ZipFileName.Replace("@ShipToID", ShipToID);
                ZipFileName = ZipFileName.Replace("@yyyyMMddHHmmss", GetExportTime()) + ".zip";
                string Pwd = Encoder.GenPWDByFilename(ZipFileName);

                FileInfo ZipFile = new FileInfo(Path.Combine(dirUpload.FullName, ZipFileName));

                Zip.ZipFiles(approvedActualTarget.FullName, ZipFile.FullName, Pwd);

                log.Info("- Zip files completed");

                approvedActualTarget.Delete();
                log.Info("- Delete temp");
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                log.Error(ex.InnerException);
            }
            finally
            {
                log.Info("End export programID '" + ProgramID + "' for ShipToID '" + ShipToID + "'");
            }
        }
    }
}
